package com.wlz.authorization.config;

import com.wlz.authorization.handler.MyAccessDeniedHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 *  Authorization 授权
 *  基于表达式的访问控制
 *     之前学习的登录用户权限判断实际上底层实现都是调用access(表达式)
 *          https://docs.spring.io/spring-security/site/docs/5.2.7.RELEASE/reference/htmlsingle/#tech-intro-access-control
 *      表达式根对象的基类是SecurityExpressionRoot，提供了一些在web和方法安全性中都可用的通用表达式。
 */
//@Configuration
//@EnableWebSecurity 基于springboot 可以不用
public class WebSecurityAntAccessConfig extends WebSecurityConfigurerAdapter {


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin();  //表单登录

        //授权
        http.authorizeRequests()
//                .antMatchers("/admin/demo").permitAll() // 不用认证
//                .antMatchers( "/admin/demo").access("permitAll()") // 不用认证 表达式的访问控制
//                .antMatchers("/admin/demo").access("hasAuthority('demo')") // 表达式的访问控制
                .antMatchers("/admin/demo").access("@mySecurityExpression.hasPermission(request,authentication)") // 自定义方法 /admin/demo?name=admin
                .anyRequest().authenticated();  //  必须认证

        http.exceptionHandling().accessDeniedHandler(new MyAccessDeniedHandler()); // 支持自定义权限受限处理，需要实现 AccessDeniedHandler接口
        http.csrf().disable();//csrf关掉

    }

    @Bean
    public PasswordEncoder passwordEncoder(){
//        return NoOpPasswordEncoder.getInstance();
        return new BCryptPasswordEncoder();
    }


}
